import {Col, Form, Input, Modal, Select, Space, Table} from "antd";
import {LabelPredicateButton, PredicateButton} from "./ShowButton.tsx";
import {EmptyIfNull, ModeProp, OrderConfig} from "./BaseCompomentDef.tsx";
import {PREDICATE_CONFIG_KEY_OPTION, PREDICATE_CONFIG_KEYS} from "../model/RouteDef.ts";
import {useState} from "react";


const PREDICATE_CONFIG_SELECT_OPTION = PREDICATE_CONFIG_KEYS.map( it => {
    return { label : it , value : it }
} )


const getRoutePredicateOption = ( predicateKey : string ) => {
    for (const eachOption of PREDICATE_CONFIG_KEY_OPTION) {
        if ( eachOption.key === predicateKey ) {
            return eachOption;
        }
    }
    return { key : predicateKey , description: "" }
}



export interface RoutePredicateProp extends ModeProp {

    predicate? : string

    onChangePredicate? : ( predicate : string ) => void

}


export const RoutePredicate = ( prop : RoutePredicateProp ) => {
    const predicate = prop.predicate || '='
    const mode = prop.mode || 'display'
    const onChangePredicate = EmptyIfNull(prop.onChangePredicate)
    const predicateKey = predicate.substring( 0 , predicate.indexOf('=') )
    const predicateVal = predicate.substring( predicate.indexOf('=') + 1 , predicate.length )
    const routePredicateOption = getRoutePredicateOption(predicateKey);

    const onChangePredicateKey = ( str : string ) => {
        onChangePredicate( str + "=" + predicateVal )
    }

    const onChangePredicateVal = ( str : string ) => {
        onChangePredicate( predicateKey + "=" + str )
    }


    return <>
        <p> { routePredicateOption.description } </p>
        <Form>
            <Form.Item label="key">
                <Select
                    disabled={ mode === 'display' }
                    options={ PREDICATE_CONFIG_SELECT_OPTION }
                    value={predicateKey}
                    onChange={ onChangePredicateKey }
                ></Select>
            </Form.Item>
            <Form.Item label="value">
                <Input.TextArea
                    readOnly={mode === 'display'}
                    onChange={ (e) => onChangePredicateVal(e.target.value as string) }
                    value={predicateVal}
                />
            </Form.Item>
        </Form>
    </>

}




interface PredicateOpt extends ModeProp {

    predicate : string

    index : number

}

const EMPTY_PREDICATE_OPT : PredicateOpt = {

    mode : 'none' ,

    predicate : 'RewritePath=' ,

    index : -1

} as const;



interface RoutePredicatesProp extends ModeProp {

    predicates? : string[]

    onAppendPredicate? : ( predicate : string ) => void

    onModifyPredicate? : ( predicate : string , index : number ) => void

    onRemovePredicate? : ( predicate : string , index : number ) => void

}

export const RoutePredicates = ( prop : RoutePredicatesProp )=> {
    const mode = prop.mode || 'display'
    const editable = mode === 'create' || mode === 'modify'
    const onAppendPredicate = prop.onAppendPredicate || (() => {} )
    const onModifyPredicate = prop.onModifyPredicate || (()=>{})
    const onRemovePredicate = EmptyIfNull( prop.onRemovePredicate )
    const predicates : OrderConfig[] =  ( prop.predicates || [] ).map( ( it , index ) => {
        return { key : index , order : index , config : it }
    })


    const [ predicateOpt , _setPredicateOpt ] = useState(EMPTY_PREDICATE_OPT)


    const _onCancelCreateOrModifyPredicate = () => {
        _setPredicateOpt( EMPTY_PREDICATE_OPT )
    }

    const _onCreatePredicate = () => {
        _setPredicateOpt( {  ...EMPTY_PREDICATE_OPT , mode : 'create' } )
    }

    const _onModifyPredicate = ( ep : OrderConfig , index : number ) => {
        _setPredicateOpt( { mode : 'modify' , index : index , predicate : ep.config } )
    }

    const _onRemovePredicate = ( ep : OrderConfig , index : number ) => {
        onRemovePredicate( ep.config , index )
    }

    const _onDisplayPredicate = ( ep : OrderConfig ) => {
        _setPredicateOpt( { mode : 'display' , index : -1 , predicate : ep.config } )
    }

    const _onChangePredicate = ( predicate : string ) => {
        _setPredicateOpt( { ...predicateOpt , predicate : predicate } )
    }

    const _onCommitPredicate = () => {
        const predicateStr = predicateOpt.predicate
        if ( predicateOpt.mode === 'modify' ) {
            onModifyPredicate( predicateStr , predicateOpt.index )
        } else if ( predicateOpt.mode === 'create' ) {
            onAppendPredicate( predicateStr )
        }
        _setPredicateOpt(EMPTY_PREDICATE_OPT)
    }

    return <>
        <Modal
            closable={false}
            onOk={ _onCommitPredicate }
            open={ predicateOpt.mode === 'modify' || predicateOpt.mode === 'create' }
            onCancel={ _onCancelCreateOrModifyPredicate }
        >
            <RoutePredicate
                mode={ predicateOpt.mode }
                predicate={ predicateOpt.predicate }
                onChangePredicate={ _onChangePredicate }
            />
        </Modal>
        <Table
            dataSource={predicates}
            title={ () =>
                <LabelPredicateButton show={ editable } label="predicates" onClick={_onCreatePredicate} >append</LabelPredicateButton>
            }
        >
            <Table.Column title="order" render={ ( _ , ep : OrderConfig )=> {
                return <> { ep.order } </>
            } } />
            <Table.Column title="config" render={ ( _ , ep : OrderConfig )=> {
                return <> { ep.config } </>
            } }  />
            <Table.Column
                width={256}
                title="action"
                render={ ( _ , ep : OrderConfig , index  )=> { return <>
                    <Space >
                        <PredicateButton show={!editable} onClick={ ()=>{ _onDisplayPredicate(ep) } } > display </PredicateButton>
                        <PredicateButton show={editable} onClick={ ()=>{ _onModifyPredicate( ep , index ) } } > modify </PredicateButton>
                        <PredicateButton show={editable} onClick={()=>{ _onRemovePredicate(ep,index) }}> delete </PredicateButton>
                    </Space>
                </>}}
            />
        </Table>

    </>


}